{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import tensorflow as tf"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'1.2.1'"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tf.__version__"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "from matplotlib import pyplot as plt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "%matplotlib inline\n",
    "tf.logging.set_verbosity(tf.logging.INFO)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "from tensorflow.examples.tutorials.mnist import input_data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Extracting ./MNIST_data/train-images-idx3-ubyte.gz\n",
      "Extracting ./MNIST_data/train-labels-idx1-ubyte.gz\n",
      "Extracting ./MNIST_data/t10k-images-idx3-ubyte.gz\n",
      "Extracting ./MNIST_data/t10k-labels-idx1-ubyte.gz\n",
      "(55000, 784)\n",
      "(55000,)\n"
     ]
    }
   ],
   "source": [
    "mnist = input_data.read_data_sets(\"./MNIST_data/\")\n",
    "print(mnist.train.images.shape)\n",
    "print(mnist.train.labels.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(5000, 784)\n",
      "(5000,)\n",
      "(10000, 784)\n",
      "(10000,)\n"
     ]
    }
   ],
   "source": [
    "print(mnist.validation.images.shape)\n",
    "print(mnist.validation.labels.shape)\n",
    "\n",
    "print(mnist.test.images.shape)\n",
    "print(mnist.test.labels.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x1aa7fac0588>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(8,8))\n",
    "\n",
    "for idx in range(16):\n",
    "    plt.subplot(4,4, idx+1)\n",
    "    plt.axis('off')\n",
    "    plt.title('[{}]'.format(mnist.train.labels[idx]))\n",
    "    plt.imshow(mnist.train.images[idx].reshape((28,28)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "after 100 training steps, the loss is 0.338888, the validation accuracy is 0.8398\n",
      "after 200 training steps, the loss is 0.591439, the validation accuracy is 0.8152\n",
      "after 300 training steps, the loss is 0.356469, the validation accuracy is 0.9272\n",
      "after 400 training steps, the loss is 0.114865, the validation accuracy is 0.9362\n",
      "after 500 training steps, the loss is 0.203468, the validation accuracy is 0.935\n",
      "after 600 training steps, the loss is 0.346768, the validation accuracy is 0.9408\n",
      "after 700 training steps, the loss is 0.0856009, the validation accuracy is 0.9494\n",
      "after 800 training steps, the loss is 0.155501, the validation accuracy is 0.9476\n",
      "after 900 training steps, the loss is 0.3018, the validation accuracy is 0.9558\n",
      "the training is finish!\n",
      "the test accuarcy is: 0.9515\n"
     ]
    }
   ],
   "source": [
    "##定义神经网络\n",
    "##定义两个placeholder分别用于图像和lable数据，另外，定义一个float类型的变量用于设置学习率\n",
    "x = tf.placeholder(\"float\", [None, 784])\n",
    "y = tf.placeholder(\"int64\", [None])\n",
    "learning_rate = tf.placeholder(\"float\")\n",
    "##为了让网络更高效的运行，多个数据会被组织成一个batch送入网络，两个placeholder的第一个维度就是batchsize，\n",
    "##因为我们这里还没有确定batchsize，所以第一个维度留空\n",
    "x = tf.placeholder(\"float\", [None, 784])\n",
    "y = tf.placeholder(\"int64\", [None])\n",
    "learning_rate = tf.placeholder(\"float\")\n",
    "def initialize(shape, stddev=0.1):\n",
    "  return tf.truncated_normal(shape, stddev=0.1)\n",
    "\n",
    "L1_units_count = 100\n",
    "\n",
    "W_1 = tf.Variable(initialize([784, L1_units_count]))\n",
    "b_1 = tf.Variable(initialize([L1_units_count]))\n",
    "logits_1 = tf.matmul(x, W_1) + b_1\n",
    "output_1 = tf.nn.relu(logits_1)\n",
    "\n",
    "L2_units_count = 10 \n",
    "W_2 = tf.Variable(initialize([L1_units_count, L2_units_count]))\n",
    "b_2 = tf.Variable(initialize([L2_units_count]))\n",
    "logits_2 = tf.matmul(output_1, W_2) + b_2  \n",
    "\n",
    "logits = logits_2\n",
    "\n",
    "## 接下来定义loss和用于优化网络的优化器\n",
    "## loss计算使用了sparse_softmax_cross_entropy_with_logits,\n",
    "## 这样做的好处是labels可以不用手动做one_hot省了一些麻烦。这里使用了sgd优化器，学习率为可以根据需要设定\n",
    "## 试试看，增大减小学习率，换个优化器再进行训练会发生什么\n",
    "cross_entropy_loss = tf.reduce_mean(\n",
    "    tf.nn.sparse_softmax_cross_entropy_with_logits(logits=logits, labels=y))\n",
    "\n",
    "optimizer = tf.train.GradientDescentOptimizer(\n",
    "    learning_rate=learning_rate).minimize(cross_entropy_loss)\n",
    "## 需要注意的是，上面的网络，最后输出的是未经softmax的原始logits，而不是概率分布， 要想看到概率分布，还需要做一下softmax\n",
    "## 将输出的结果与正确结果进行对比，即可得到我们的网络输出结果的准确率\n",
    "pred = tf.nn.softmax(logits)\n",
    "correct_pred = tf.equal(tf.argmax(pred, 1), y)\n",
    "accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))\n",
    "## saver用于保存或恢复训练的模型。\n",
    "batch_size = 32\n",
    "trainig_step = 1000\n",
    "\n",
    "saver = tf.train.Saver()\n",
    "## 以上定义的所有操作，均为计算图，也就是仅仅是定义了网络的结构，实际需要运行的话，还需要创建一个session，并将数据填入网络中\n",
    "with tf.Session() as sess:\n",
    "    sess.run(tf.global_variables_initializer())\n",
    "\n",
    "    #定义验证集与测试集\n",
    "    validate_data = {\n",
    "        x: mnist.validation.images,\n",
    "        y: mnist.validation.labels,\n",
    "    }\n",
    "    test_data = {x: mnist.test.images, y: mnist.test.labels}\n",
    "\n",
    "    for i in range(trainig_step):\n",
    "        xs, ys = mnist.train.next_batch(batch_size)\n",
    "        _, loss = sess.run(\n",
    "            [optimizer, cross_entropy_loss],\n",
    "            feed_dict={\n",
    "                x: xs,\n",
    "                y: ys,\n",
    "                learning_rate: 0.3\n",
    "            })\n",
    "\n",
    "        #每100次训练打印一次损失值与验证准确率\n",
    "        if i > 0 and i % 100 == 0:\n",
    "            validate_accuracy = sess.run(accuracy, feed_dict=validate_data)\n",
    "            print(\n",
    "                \"after %d training steps, the loss is %g, the validation accuracy is %g\"\n",
    "                % (i, loss, validate_accuracy))\n",
    "            saver.save(sess, './model.ckpt', global_step=i)\n",
    "\n",
    "    print(\"the training is finish!\")\n",
    "    #最终的测试准确率\n",
    "    acc = sess.run(accuracy, feed_dict=test_data)\n",
    "    print(\"the test accuarcy is:\", acc)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Restoring parameters from ./model.ckpt-900\n",
      "0.9375\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x1aa7e3579b0>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "## 下面，用我们训练的模型做一个测试。\n",
    "with tf.Session() as sess:\n",
    "    ckpt = tf.train.get_checkpoint_state('./')\n",
    "    if ckpt and ckpt.model_checkpoint_path:\n",
    "        saver.restore(sess, ckpt.model_checkpoint_path)\n",
    "        final_pred, acc = sess.run(\n",
    "            [pred, accuracy],\n",
    "            feed_dict={\n",
    "                x: mnist.test.images[:16],\n",
    "                y: mnist.test.labels[:16]\n",
    "            })\n",
    "        orders = np.argsort(final_pred)\n",
    "        plt.figure(figsize=(8, 8))\n",
    "        print(acc)\n",
    "        for idx in range(16):\n",
    "            order = orders[idx, :][-1]\n",
    "            prob = final_pred[idx, :][order]\n",
    "            plt.subplot(4, 4, idx + 1)\n",
    "            plt.axis('off')\n",
    "            plt.title('{}: [{}]-[{:.1f}%]'.format(mnist.test.labels[idx],\n",
    "                                                  order, prob * 100))\n",
    "            plt.imshow(mnist.test.images[idx].reshape((28, 28)))\n",
    "\n",
    "    else:\n",
    "        pass\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Extracting ./MNIST_data/train-images-idx3-ubyte.gz\n",
      "Extracting ./MNIST_data/train-labels-idx1-ubyte.gz\n",
      "Extracting ./MNIST_data/t10k-images-idx3-ubyte.gz\n",
      "Extracting ./MNIST_data/t10k-labels-idx1-ubyte.gz\n"
     ]
    }
   ],
   "source": [
    "## 以上提供的参数运行出来的结果，只看上面几个数字还是很不错的，但是总体准确率不太理想。\n",
    "\n",
    "## 模型优化改进\n",
    "#读取数据集\n",
    "mnist_new = input_data.read_data_sets(\"./MNIST_data/\",one_hot=True)\n",
    "#定义输入,输出\n",
    "x = tf.placeholder(\"float\", [None, 784])\n",
    "y = tf.placeholder(\"int64\", [None, 10])\n",
    "#隐层神经元个数\n",
    "L1_units_count = 256\n",
    "L2_units_count = 64\n",
    "#输出层神经元个数\n",
    "L3_units_count = 10\n",
    "# 优化方法参数\n",
    "learning_rate_base = 0.3  # 基础学习率\n",
    "learning_rate_decay = 0.99  # 学习率的衰减率\n",
    "regularization_rate = 0.001  # 正则化项在损失函数中的系数\n",
    "#训练参数\n",
    "batch_size = 256\n",
    "trainig_step = 20000\n",
    "\n",
    "# 存储训练轮数，设置为不可训练\n",
    "global_step = tf.Variable(0, trainable=False)\n",
    "\n",
    "def initialize(shape, stddev=0.1):\n",
    "  return tf.truncated_normal(shape, stddev=0.1)\n",
    "#隐层1:256个神经元\n",
    "W_1 = tf.Variable(initialize([784, L1_units_count]))\n",
    "b_1 = tf.Variable(initialize([L1_units_count]))\n",
    "logits_1 = tf.matmul(x, W_1) + b_1\n",
    "output_1 = tf.nn.relu(logits_1)#使用ReLU激活函数激活\n",
    "\n",
    "#隐层2:64个神经元\n",
    "W_2 = tf.Variable(initialize([L1_units_count, L2_units_count]))\n",
    "b_2 = tf.Variable(initialize([L2_units_count]))\n",
    "logits_2 = tf.matmul(output_1, W_2) + b_2\n",
    "output_2 = tf.nn.relu(logits_2)#使用ReLU激活函数激活\n",
    "\n",
    "\n",
    "#输出层:10个神经元\n",
    "W_3 = tf.Variable(initialize([L2_units_count, L3_units_count]))\n",
    "b_3 = tf.Variable(initialize([L3_units_count]))\n",
    "logits_3 = tf.matmul(output_2, W_3) + b_3\n",
    "\n",
    "logits_new = logits_3\n",
    "\n",
    "#loss函数与优化器\n",
    "#采用softmax + 交叉熵 + L2正则，与eta指数衰减 + 随机梯度下降\n",
    "# 设置正则化方法\n",
    "regularizer = tf.contrib.layers.l2_regularizer(regularization_rate)  # 定义L2正则化损失函数\n",
    "regularization = regularizer(W_1) + regularizer(W_2) + regularizer(W_3)  # 计算模型的正则化损失\n",
    "\n",
    "# 设置指数衰减法\n",
    "learning_rate = tf.train.exponential_decay(learning_rate_base, \n",
    "                                           global_step, \n",
    "                                           mnist_new.train.num_examples / batch_size,\n",
    "                                           learning_rate_decay)\n",
    "\n",
    "# softmax激活的交叉熵计算\n",
    "cross_entropy_loss = tf.reduce_mean(\n",
    "    tf.nn.softmax_cross_entropy_with_logits(logits=logits_new, labels=y))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 总损失等于交叉熵损失和正则化损失的和\n",
    "loss_sum = cross_entropy_loss + regularization\n",
    "# 随机梯度下降优化器\n",
    "optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss_sum, global_step=global_step)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [],
   "source": [
    "##评估性能\n",
    "pred_new = tf.nn.softmax(logits_new)\n",
    "correct_pred_new = tf.equal(tf.argmax(pred_new, 1), tf.argmax(y, 1))\n",
    "accuracy = tf.reduce_mean(tf.cast(correct_pred_new, tf.float32))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [],
   "source": [
    "#保存模型\n",
    "saver = tf.train.Saver()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "after 2500 training steps, the loss is 0.348367, the validation accuracy is 0.9758\n",
      "after 5000 training steps, the loss is 0.162512, the validation accuracy is 0.9802\n",
      "after 7500 training steps, the loss is 0.131217, the validation accuracy is 0.9824\n",
      "after 10000 training steps, the loss is 0.125121, the validation accuracy is 0.983\n",
      "after 12500 training steps, the loss is 0.115017, the validation accuracy is 0.9826\n",
      "after 15000 training steps, the loss is 0.127557, the validation accuracy is 0.9814\n",
      "after 17500 training steps, the loss is 0.123677, the validation accuracy is 0.9824\n",
      "the training is finish!\n",
      "the test accuarcy is: 0.983\n"
     ]
    }
   ],
   "source": [
    "#训练模型\n",
    "with tf.Session() as sess:\n",
    "    sess.run(tf.global_variables_initializer())\n",
    "    #定义验证集与测试集\n",
    "    validate_data = {\n",
    "        x: mnist_new.validation.images,\n",
    "        y: mnist_new.validation.labels,\n",
    "    }\n",
    "    test_data = {\n",
    "        x: mnist_new.test.images, \n",
    "        y: mnist_new.test.labels\n",
    "    }\n",
    "    for i in range(trainig_step):\n",
    "        xs, ys = mnist_new.train.next_batch(batch_size)\n",
    "        _, loss = sess.run(\n",
    "            [optimizer, loss_sum],\n",
    "            feed_dict={\n",
    "                x: xs,\n",
    "                y: ys\n",
    "            })\n",
    "\n",
    "        #每2500次训练打印一次损失值与验证准确率\n",
    "        if i > 0 and i % 2500 == 0:\n",
    "            validate_accuracy = sess.run(accuracy, feed_dict=validate_data)\n",
    "            print(\n",
    "                \"after %d training steps, the loss is %g, the validation accuracy is %g\"\n",
    "                % (i, loss, validate_accuracy))\n",
    "            saver.save(sess, './mode2.ckpt', global_step=i)\n",
    "\n",
    "    print(\"the training is finish!\")\n",
    "    \n",
    "    #最终的测试准确率\n",
    "    acc = sess.run(accuracy, feed_dict=test_data)\n",
    "    print(\"the test accuarcy is:\", acc)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
